home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Cafe 3
/
Visual Cafe 3.ISO
/
Vcafe
/
JFC.bin
/
HTMLWriter.java
< prev
next >
Wrap
Text File
|
1998-06-30
|
62KB
|
2,222 lines
/*
* @(#)HTMLWriter.java 1.31 98/04/12
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.text.html;
import java.util.*;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import com.sun.java.swing.text.*;
// PENDING(prinz) for the next release this class will
// be completely rewritten. The attribute policy will be
// different enabling a small amount to code to generate
// the output rather than it's current enormous size.
// Additionally, writing styled documents from JTextPane
// will work. This class will become public after being
// rewritten, to allow subclasses to refine it's behavior.
/**
* Class to output in writing HTML to a writer or output stream.
* Things that will differ from original source:
* 1. Writing out "known" attributes. Any attributes (e.g.,"foo=x"
* will not be restored.
* 2. Will convert chars ______ to NNN;.
*
* @author Jill Nakata
* @version 1.31 04/12/98
*/
class HTMLWriter {
private Hashtable branchTable;
private Hashtable leafTable;
private boolean lowercase = true;
private boolean indenting = false;
private boolean writePre = false;
private int nPrelines = 0;
private int inFont = 0;
private static final String GENERIC = "generic";
private static final String SPACE = " ";
private static final String EQUAL = "=";
private static final String QUOTE = "\"";
private static final String CR = "\n";
/**
* Creates a new HTMLWriter object.
*/
public HTMLWriter() {
initializeBranchTable();
initializeLeafTable();
}
/**
* Writes the document to a stream as HTML starting from root.
*
* @param os the output stream
* @param doc the HTML document
* @exception Exception on any failure
*/
public void write(OutputStream os, StyledDocument doc) throws Exception {
OutputStreamWriter osw = new OutputStreamWriter(os);
write(osw, doc);
osw.flush();
}
/**
* Writes the document to a writer as HTML starting from root.
*
* @param w the writer
* @param doc the HTML document
*/
public void write(Writer w, StyledDocument doc) throws IOException {
AbstractDocument.BranchElement root =
(AbstractDocument.BranchElement)doc.getDefaultRootElement();
writeStartTag(w, Constants.HTML);
writeHead(w, root);
// Write BODY contents by walking the element tree starting from root.
writeBranch(w, "", root);
writeEndTag(w, Constants.HTML);
w.flush();
}
/**
* Adds an attribute translator.
*
* @param tag the translator name
* @param trans the translator
*/
public void setBranchTranslator(String tag, BranchTranslator trans) {
branchTable.put(tag, trans);
}
/**
* Gets a translator with a given name.
*
* @param tag the name
* @return the translator
*/
public BranchTranslator getBranchTranslator(String tag) {
BranchTranslator bt = (BranchTranslator)branchTable.get(tag);
HTMLDebug.println("getBranchTranslator for " + tag);
//
// If no translator found for this tag,
// use the generic one.
//
if (bt == null) {
bt = getBranchTranslator(GENERIC);
System.out.println("HTMLWriter.getBranchTranslator: " +
"Using genericBranchTranslator for " + tag);
}
return bt;
}
/**
* Removes a translator.
*
* @param tag the translator name
*/
public void removeBranchTranslator(String tag) {
branchTable.remove(tag);
}
/**
* Adds an attribute translator.
*
* @param tag the translator name
* @param trans the translator
*/
public void setLeafTranslator(String tag, LeafTranslator trans) {
leafTable.put(tag, trans);
}
/**
* Gets a translator with a given name.
*
* @param tag the name
* @return the translator
*/
public LeafTranslator getLeafTranslator(String tag) {
LeafTranslator lt = (LeafTranslator)leafTable.get(tag);
HTMLDebug.println("getLeafTranslator for " + tag);
//
// If no translator found for this tag,
// use the generic one.
//
if (lt == null) {
HTMLDebug.println("getLeafTranslator generic ");
lt = getLeafTranslator(AbstractDocument.ContentElementName);
//System.out.println("HTMLWriter.getLeafTranslator: " +
//"Using contentTranslator for " + tag);
}
return lt;
}
/**
* Removes a translator.
*
* @param tag the translator name
*/
public void removeLeafTranslator(String tag) {
leafTable.remove(tag);
}
// THIS IS BOGUS AND SHOULD BE REMOVED
static class HTMLDebug {
public static boolean dbg = false;
public static void setDebug(boolean d)
{
dbg = d;
}
public static void println(String str)
{
if(dbg)
System.out.println(str);
}
public static boolean debugOn()
{
return dbg;
}
}
interface BranchTranslator {
/**
* Translates a branch element for writing.
*
* @param w the writer
* @param e the element
*/
public void translate(Writer w, Element e);
}
interface LeafTranslator {
/**
* Translates an html leaf for writing.
*
* @param w the writer
* @param parent the element's parent
* @param e the element
*/
public void translate(Writer w, Element parent, Element e);
}
/**
* Branch Translators...
*/
class GenericBranchTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
String tag;
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
AttributeSet style = a.getResolveParent();
String elementName = e.getName();
if (elementName.equals(AbstractDocument.ParagraphElementName)) {
tag = (String)style.getAttribute(AttributeSet.NameAttribute);
// Hack: This name may be "ul li p" so just use "p" translator.
if (tag.endsWith(" p"))
tag = "p";
}
else
tag = elementName;
tag = convertCase(tag);
write(w, "<" + tag + ">");
}
}
class HeadTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
write(w, "<" + convertCase(Constants.HEAD) + ">\n");
StyledDocument doc = (StyledDocument)e.getDocument();
//
// Write Title, if exists.
//
String title = (String)doc.getProperty(Document.TitleProperty);
if (title != null) {
if (indenting == true)
write(w, " <" + convertCase(Constants.TITLE) + ">" + title +
"</" + convertCase(Constants.TITLE) + ">\n");
else
write(w, "<" + convertCase(Constants.TITLE) + ">" + title +
"</" + convertCase(Constants.TITLE) + ">\n");
}
//
// Write Base Href, if exists.
//
String href = (String)doc.getProperty(Constants.BaseHrefProperty);
if (href != null) {
write(w, " <" + convertCase(Constants.BASE) + " " + convertCase(Constants.HREF) +
"=\"" + href + "\">\n");
}
write(w, "</" + convertCase(Constants.HEAD) + ">\n");
}
}
class BodyTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Write out "<body" and attributes.
write(w, "<" + convertCase(Constants.BODY));
AttributeSet a = e.getAttributes();
// Write out " text=#ff0000", if defined.
String value = (String)a.getAttribute(Constants.TEXT);
if (value != null) {
write(w, SPACE + convertCase(Constants.TEXT) + EQUAL);
write(w, convertCase(value));
}
// Write out " background=#ff0000", if defined.
value = (String)a.getAttribute(Constants.BACKGROUND);
if (value != null) {
write(w, SPACE + convertCase(Constants.BACKGROUND) + EQUAL);
write(w, value);
}
// Write out " bgcolor=#ff0000", if defined.
value = (String)a.getAttribute(Constants.BGCOLOR);
if (value != null) {
write(w, SPACE + convertCase(Constants.BGCOLOR) + EQUAL);
write(w, convertCase(value));
}
// Write out " link=#ff0000", if defined.
value = (String)a.getAttribute(Constants.LINK);
if (value != null) {
write(w, SPACE + convertCase(Constants.LINK) + EQUAL);
write(w, convertCase(value));
}
// Write out " VLINK=#ff0000", if defined.
value = (String)a.getAttribute(Constants.VLINK);
if (value != null) {
write(w, SPACE + convertCase(Constants.VLINK) + EQUAL);
write(w, convertCase(value));
}
// Write out " ALINK=#ff0000", if defined.
value = (String)a.getAttribute(Constants.ALINK);
if (value != null) {
write(w, SPACE + convertCase(Constants.ALINK) + EQUAL);
write(w, convertCase(value));
}
write(w, ">");
}
}
class HTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
AttributeSet style = a.getResolveParent();
String htag = (String)style.getAttribute(AttributeSet.NameAttribute);
// Write out "<h1"
write(w, "<");
write(w, convertCase(htag));
// Write out " align=left,center,right", if defined.
String value = (String)a.getAttribute(Constants.ALIGN);
if (value != null) {
write(w, SPACE + convertCase(Constants.ALIGN) + EQUAL);
write(w, convertCase(value));
}
write(w, ">");
}
}
class LiTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
// Write out "<li"
write(w, "<");
write(w, convertCase(Constants.LI));
// Write out " type=A, a, i"
String value = (String)a.getAttribute(Constants.TYPE);
if (value != null) {
write(w, SPACE + convertCase(Constants.TYPE) + EQUAL);
value = convertCase(value);
write(w, value);
}
// Write out " value=9"
value = (String)a.getAttribute(Constants.VALUE);
if (value != null) {
write(w, SPACE + convertCase(Constants.VALUE));
value = convertCase(value);
write(w, value);
}
write(w, ">");
}
}
class PTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
// Write out "<p"
write(w, "<");
write(w, convertCase(Constants.P));
// Write out " align=center,right,left"
String value = (String)a.getAttribute(Constants.ALIGN);
if (value != null) {
write(w, SPACE + convertCase(Constants.ALIGN) + EQUAL);
write(w, convertCase(value));
}
write(w, ">");
}
}
class PreTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
AttributeSet a = e.getAttributes();
// Write out "<pre"
write(w, "<" + convertCase(Constants.PRE));
// Write out " width=xx", if exists.
String value = (String)a.getAttribute(Constants.WIDTH);
if (value != null) {
write(w, SPACE + convertCase(Constants.WIDTH) + EQUAL);
write(w, convertCase(value));
}
write(w, ">");
// Get the number of prelines to process for this Pre tag.
// This is the number of prelines to write out.
// Subtract the last one as this was the \n that was added
// and we don't want to process the last \n.
nPrelines = e.getElementCount();
}
}
class DlTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
AttributeSet a = e.getAttributes();
// Write out "<dl"
write(w, "<" + convertCase(Constants.DL));
// Write out " compact", if exists.
String value = (String)a.getAttribute(Constants.COMPACT);
if (value == Constants.NULL_ATTRIBUTE) {
write(w, SPACE + convertCase(Constants.COMPACT));
}
write(w, ">\n");
}
}
class DtTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
AttributeSet a = e.getAttributes();
// Write out "<dt"
write(w, "<" + convertCase(Constants.DT) + ">");
}
}
class DdTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
AttributeSet a = e.getAttributes();
// Write out "<dd>"
write(w, "<" + convertCase(Constants.DD) + ">");
}
}
class PreLineTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Decrement the number of prelines left to process
// for this Pre tag.
nPrelines--;
// Write out first content in pre line only.
writePre = true;
}
}
class UlTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
// Write out "<ul"
write(w, "<");
write(w, convertCase(Constants.UL));
// Write out " type=disc, circle, square"
String value = (String)a.getAttribute(Constants.TYPE);
if (value != null) {
write(w, SPACE + convertCase(Constants.TYPE) + EQUAL);
write(w, convertCase(value));
}
// Write out " compact"
value = (String)a.getAttribute(Constants.COMPACT);
if (value == Constants.NULL_ATTRIBUTE) {
write(w, SPACE + convertCase(Constants.COMPACT));
}
write(w, ">\n");
}
}
class OlTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
// Write out "<ol"
write(w, "<");
write(w, convertCase(Constants.OL));
// Write out " start=3"
String value = (String)a.getAttribute(Constants.START);
if (value != null) {
write(w, SPACE + convertCase(Constants.START) + EQUAL);
write(w, convertCase(value));
}
// Write out " type="i""
value = (String)a.getAttribute(Constants.TYPE);
if (value != null) {
write(w, SPACE + convertCase(Constants.TYPE) + EQUAL);
write(w, QUOTE + convertCase(value) + QUOTE);
}
// Write out " compact"
value = (String)a.getAttribute(Constants.COMPACT);
if (value == Constants.NULL_ATTRIBUTE) {
write(w, SPACE + convertCase(Constants.COMPACT));
}
write(w, ">\n");
}
}
class MenuTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
// Write out "<menu"
write(w, "<");
write(w, convertCase(Constants.MENU));
// Write out " type=disc, circle, square"
String value = (String)a.getAttribute(Constants.TYPE);
if (value != null) {
write(w, SPACE + convertCase(Constants.TYPE) + EQUAL);
write(w, convertCase(value));
}
write(w, ">\n");
}
}
class BlockquoteTranslator implements BranchTranslator {
public void translate(Writer w, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
// Write out "<blockquote"
write(w, "<");
write(w, convertCase(Constants.BLOCKQUOTE));
write(w, ">\n");
}
}
/**
* Leaf Translators...
*/
class GenericLeafTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes.
String tag = e.getName();
write(w, "<" + convertCase(tag) + ">");
}
}
class ContentTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
Stack tagStack = new Stack();
Vector tagStyles = new Vector();
AttributeSet style = e.getAttributes();
AttributeSet pattrs = parent.getAttributes();
AttributeSet pstyle = pattrs.getResolveParent(); // Paragraph
//
// First write out any logical style tags.
//
Enumeration names = style.getAttributeNames();
while (names.hasMoreElements()) {
Object name = (Object)names.nextElement();
if (!name.toString().startsWith("$") &&
style.getAttribute(name).equals("true")) {
HTMLDebug.println(name + "=" + style.getAttribute(name));
//
// Add the name of this attribute
//
tagStack.push(name);
write(w, "<" + name + ">");
//
// Add the style for this tag to the list of styles
//
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet tagstyle = doc.getStyle(name.toString());
if (tagstyle != null)
tagStyles.addElement(tagstyle);
}
}
// Write out styles differ from the tag styles.
writeContent(w, tagStyles, e, parent);
while (tagStack.size() != 0) {
String name = (String)tagStack.peek();
write(w, "</" + name + ">");
tagStack.pop();
}
}
}
class ImgTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out img tag and attributes.
AttributeSet a = e.getAttributes();
//
// SRC is required for img so make sure src exists
// before writing out "<img"
//
String value = (String)a.getAttribute(Constants.SRC);
if (value == null) {
System.out.println("HTMLWriter.ImgTranslator: No src attribute for img.");
return;
}
//
// Write out "<img src=value"
//
write(w, "<" + convertCase(Constants.IMG) + " " +
convertCase(Constants.SRC) + "=" + QUOTE + value.toLowerCase() + QUOTE);
//
// Write out " height=value", if exists.
//
value = (String)a.getAttribute(Constants.HEIGHT);
if (value != null) {
write(w, SPACE + convertCase(Constants.HEIGHT) + EQUAL + convertCase(value));
}
//
// Write out " width=value", if exists.
//
value = (String)a.getAttribute(Constants.WIDTH);
if (value != null) {
write(w, SPACE + convertCase(Constants.WIDTH) + EQUAL + convertCase(value));
}
//
// Write out " align=value", if exists.
//
value = (String)a.getAttribute(Constants.ALIGN);
if (value != null) {
write(w, SPACE + convertCase(Constants.ALIGN) + EQUAL + convertCase(value));
}
//
// Write out " hspace=value", if exists.
//
value = (String)a.getAttribute(Constants.HSPACE);
if (value != null) {
write(w, SPACE + convertCase(Constants.HSPACE) + EQUAL + value);
}
//
// Write out " vspace=value", if exists.
//
value = (String)a.getAttribute(Constants.VSPACE);
if (value != null) {
write(w, SPACE + convertCase(Constants.VSPACE) + EQUAL + value);
}
//
//
// Write out " alt=value", if exists.
//
value = (String)a.getAttribute(Constants.ALT);
if (value != null) {
write(w, SPACE + convertCase(Constants.ALT) + EQUAL + QUOTE + value + QUOTE);
}
//
// Write out " border=value", if exists.
//
value = (String)a.getAttribute(Constants.BORDER);
if (value != null) {
write(w, SPACE + convertCase(Constants.BORDER) + EQUAL + value);
}
//
// Write out " usemap", if set.
//
value = (String)a.getAttribute(Constants.USEMAP);
if (value != null) {
write(w, SPACE + convertCase(Constants.USEMAP));
}
//
// Write out " ismap", if set.
//
value = (String)a.getAttribute(Constants.ISMAP);
if (value != null) {
write(w, SPACE + convertCase(Constants.ISMAP));
}
//
// Close off img tag.
//
write(w, ">");
}
}
class FontTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
AttributeSet style = e.getAttributes();
AttributeSet pattrs = parent.getAttributes();
AttributeSet pstyle = pattrs.getResolveParent(); // Paragraph
// Write "<font"
if (style.isDefined(StyleConstants.Foreground) ||
style.isDefined(StyleConstants.FontSize) ||
style.isDefined(StyleConstants.FontFamily)) {
inFont++;
write(w, "<" + convertCase(Constants.FONT));
}
// Write " color=red"
if (style.isDefined(StyleConstants.Foreground)) {
Color fg = StyleConstants.getForeground(style);
try {
String hexstr = Utilities.colorToHex(fg);
write(w, " " + convertCase(Constants.COLOR) + "=" + convertCase(hexstr));
} catch (Throwable ex) {
HTMLDebug.println("Unable to convert Color string:" + fg);
}
}
//
// Write " size=+n"
//
if (style.isDefined(StyleConstants.FontSize)) {
StyleSheet ss = StyleReader.getStyleSheet();
int ptSize = StyleConstants.getFontSize(style);
// Convert pt size to a relative value before appending.
int relSize = ss.getRelSize(ptSize);
if (relSize < 0)
write(w, " " + convertCase(Constants.SIZE) + "=" + relSize);
else
write(w, " " + convertCase(Constants.SIZE) + "=+" + relSize);
}
// Write " face=times"
// Fix later, this attribute should go away, not 3.2!
if (!pstyle.isDefined(StyleConstants.FontFamily) &&
style.isDefined(StyleConstants.FontFamily)) {
String font = StyleConstants.getFontFamily(style);
write(w, " " + convertCase(Constants.FACE) + "=\"" + font + "\"");
}
// Close off <font, if we wrote attributes for this content.
if (inFont > 0) {
write(w, ">");
}
}
}
class HrTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
// Write out "<hr"
write(w, "<");
write(w, convertCase(Constants.HR));
// Write out " align=left,center,right"
String value = (String)a.getAttribute(Constants.ALIGN);
if (value != null) {
write(w, SPACE + convertCase(Constants.ALIGN) + EQUAL);
write(w, convertCase(value));
}
// Write out " noshade"
value = (String)a.getAttribute(Constants.NOSHADE);
if (value != null) {
write(w, SPACE + convertCase(Constants.NOSHADE));
write(w, convertCase(value));
}
// Write out " size=12"
value = (String)a.getAttribute(Constants.SIZE);
if (value != null) {
write(w, SPACE + convertCase(Constants.SIZE) + EQUAL);
write(w, value);
}
// Write out " width=5,10%"
value = (String)a.getAttribute(Constants.WIDTH);
if (value != null) {
write(w, SPACE + convertCase(Constants.WIDTH));
write(w, value);
}
write(w, ">\n");
}
}
class ATranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<a"
write(w, "<");
write(w, convertCase(Constants.A));
// Write out " href="xxx""
String value = (String)a.getAttribute(Constants.HREF);
if (value != null) {
write(w, SPACE + convertCase(Constants.HREF) + EQUAL);
write(w, QUOTE + value + QUOTE);
}
// Write out " name="xxx""
value = (String)a.getAttribute(Constants.NAME);
if (value != null) {
write(w, SPACE + convertCase(Constants.NAME) + EQUAL);
write(w, QUOTE + value + QUOTE);
}
// Write out " rel=next,prev"
value = (String)a.getAttribute(Constants.REL);
if (value != null) {
write(w, SPACE + convertCase(Constants.REL) + EQUAL);
write(w, value);
}
// Write out " rev=next,prev,..."
value = (String)a.getAttribute(Constants.REV);
if (value != null) {
write(w, SPACE + convertCase(Constants.REV));
write(w, value);
}
// Write out " title="xxx""
value = (String)a.getAttribute(Constants.TITLE);
if (value != null) {
write(w, SPACE + convertCase(Constants.TITLE));
write(w, QUOTE + value + QUOTE);
}
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.A);
// Write out styles differ from the A style.
// Write out content for A tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <a>
write(w, "</" + convertCase(Constants.A) + ">");
}
}
class CodeTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<code"
write(w, "<");
write(w, convertCase(Constants.CODE));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.CODE);
// Write out styles differ from the CODE style.
// Write out content for CODE tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <code>
write(w, "</" + convertCase(Constants.CODE) + ">");
}
}
class EmTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<em"
write(w, "<");
write(w, convertCase(Constants.EM));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.EM);
// Write out styles differ from the EM style.
// Write out content for EM tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <em>
write(w, "</" + convertCase(Constants.EM) + ">");
}
}
class CiteTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<cite"
write(w, "<");
write(w, convertCase(Constants.CITE));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.CITE);
// Write out styles differ from the CITE style.
// Write out content for CITE tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <cite>
write(w, "</" + convertCase(Constants.CITE) + ">");
}
}
class StrikeTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<strike"
write(w, "<");
write(w, convertCase(Constants.STRIKE));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.STRIKE);
// Write out styles differ from the STRIKE style.
// Write out content for STRIKE tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <strike>
write(w, "</" + convertCase(Constants.STRIKE) + ">");
}
}
class SubTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<sub"
write(w, "<");
write(w, convertCase(Constants.SUB));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.SUB);
// Write out styles differ from the SUB style.
// Write out content for SUB tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <sub>
write(w, "</" + convertCase(Constants.SUB) + ">");
}
}
class TtTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<tt"
write(w, "<");
write(w, convertCase(Constants.TT));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.TT);
// Write out styles differ from the TT style.
// Write out content for TT tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <tt>
write(w, "</" + convertCase(Constants.TT) + ">");
}
}
class SupTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<sup"
write(w, "<");
write(w, convertCase(Constants.SUP));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.SUP);
// Write out styles differ from the SUP style.
// Write out content for SUP tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <sup>
write(w, "</" + convertCase(Constants.SUP) + ">");
}
}
class BigTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<big"
write(w, "<");
write(w, convertCase(Constants.BIG));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.BIG);
// Write out styles differ from the BIG style.
// Write out content for BIG tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <big>
write(w, "</" + convertCase(Constants.BIG) + ">");
}
}
class SmallTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<small"
write(w, "<");
write(w, convertCase(Constants.SMALL));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.SMALL);
// Write out styles differ from the SMALL style.
// Write out content for SMALL tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <small>
write(w, "</" + convertCase(Constants.SMALL) + ">");
}
}
class DfnTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<dfn"
write(w, "<");
write(w, convertCase(Constants.DFN));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.DFN);
// Write out styles differ from the DFN style.
// Write out content for DFN tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <dfn>
write(w, "</" + convertCase(Constants.DFN) + ">");
}
}
class KbdTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<kbd"
write(w, "<");
write(w, convertCase(Constants.KBD));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.KBD);
// Write out styles differ from the KBD style.
// Write out content for KBD tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <kbd>
write(w, "</" + convertCase(Constants.KBD) + ">");
}
}
class SampTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<samp"
write(w, "<");
write(w, convertCase(Constants.SAMP));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.SAMP);
// Write out styles differ from the SAMP style.
// Write out content for SAMP tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <samp>
write(w, "</" + convertCase(Constants.SAMP) + ">");
}
}
class StrongTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<strong"
write(w, "<");
write(w, convertCase(Constants.STRONG));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.STRONG);
// Write out styles differ from the STRONG style.
// Write out content for STRONG tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <strong>
write(w, "</" + convertCase(Constants.STRONG) + ">");
}
}
class VarTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes
AttributeSet a = e.getAttributes();
// Write out "<var"
write(w, "<");
write(w, convertCase(Constants.VAR));
// Write out ">"
write(w, ">");
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet astyle = doc.getStyle(Constants.VAR);
// Write out styles differ from the VAR style.
// Write out content for VAR tag
Vector tagStyles = new Vector();
if (astyle != null)
tagStyles.addElement(astyle);
writeContent(w, tagStyles, e, parent);
// Close off <var>
write(w, "</" + convertCase(Constants.VAR) + ">");
}
}
class PreLeafTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
StyledDocument doc = (StyledDocument)e.getDocument();
AttributeSet prestyle = doc.getStyle(Constants.PRE);
// Write out styles that differ from PRE style only.
// then write out the actual text.
Vector tagStyles = new Vector();
if (prestyle != null)
tagStyles.addElement(prestyle);
writeContent(w, tagStyles, e, parent);
}
}
class BaseFontTranslator implements LeafTranslator {
public void translate(Writer w, Element parent, Element e) {
// Write out tag and attributes.
AttributeSet a = e.getAttributes();
// Write out "<basefont"
write(w, "<");
write(w, convertCase(Constants.BASEFONT));
// Write out " size=1"
String value = (String)a.getAttribute(Constants.SIZE);
if (value != null) {
write(w, SPACE + convertCase(Constants.SIZE) + EQUAL);
write(w, value);
}
write(w, ">");
}
}
/**
* Initialize branch table translators.
*/
private void initializeBranchTable() {
branchTable = new Hashtable();
setBranchTranslator(GENERIC, new GenericBranchTranslator());
setBranchTranslator(Constants.BLOCKQUOTE, new BlockquoteTranslator());
setBranchTranslator(Constants.BODY, new BodyTranslator());
setBranchTranslator(Constants.DD, new DdTranslator());
setBranchTranslator(Constants.DL, new DlTranslator());
setBranchTranslator(Constants.DT, new DtTranslator());
setBranchTranslator(Constants.HEAD, new HeadTranslator());
setBranchTranslator(Constants.H1, new HTranslator());
setBranchTranslator(Constants.H2, new HTranslator());
setBranchTranslator(Constants.H3, new HTranslator());
setBranchTranslator(Constants.H4, new HTranslator());
setBranchTranslator(Constants.H5, new HTranslator());
setBranchTranslator(Constants.H6, new HTranslator());
setBranchTranslator(Constants.LI, new LiTranslator());
setBranchTranslator(Constants.MENU, new MenuTranslator());
setBranchTranslator(Constants.OL, new OlTranslator());
setBranchTranslator(Constants.P, new PTranslator());
setBranchTranslator(Constants.PRE, new PreTranslator());
setBranchTranslator(Constants.PRELINE, new PreLineTranslator());
setBranchTranslator(Constants.UL, new UlTranslator());
// more here
}
/**
* Initialize leaf table translators.
*/
private void initializeLeafTable() {
leafTable = new Hashtable();
setLeafTranslator(GENERIC, new GenericLeafTranslator());
setLeafTranslator(AbstractDocument.ContentElementName, new ContentTranslator());
setLeafTranslator(StyleConstants.IconElementName, new ImgTranslator());
setLeafTranslator(Constants.IMG, new ImgTranslator());
setLeafTranslator(Constants.FONT, new FontTranslator());
setLeafTranslator(Constants.HR, new HrTranslator());
setLeafTranslator(Constants.BASEFONT, new BaseFontTranslator());
setLeafTranslator(Constants.A, new ATranslator());
setLeafTranslator(Constants.BIG, new BigTranslator());
setLeafTranslator(Constants.SMALL, new SmallTranslator());
setLeafTranslator(Constants.CODE, new CodeTranslator());
setLeafTranslator(Constants.CITE, new CiteTranslator());
setLeafTranslator(Constants.STRIKE, new StrikeTranslator());
setLeafTranslator(Constants.SUB, new SubTranslator());
setLeafTranslator(Constants.SUP, new SupTranslator());
setLeafTranslator(Constants.DFN, new DfnTranslator());
setLeafTranslator(Constants.KBD, new KbdTranslator());
setLeafTranslator(Constants.SAMP, new SampTranslator());
setLeafTranslator(Constants.STRONG, new StrongTranslator());
setLeafTranslator(Constants.VAR, new VarTranslator());
setLeafTranslator(Constants.EM, new EmTranslator());
setLeafTranslator(Constants.PRE, new PreLeafTranslator());
setLeafTranslator(Constants.TT, new TtTranslator());
// more here
}
/**
* Write the leaf tag.
*/
public void writeLeaf(Writer w, String indent, Element parent, Element e) {
String name = e.getName();
LeafTranslator lt = null;
//
// If this is "content", then see if there is a more
// specific tag translator identified by the HTMLTagAttribute
// (e.g., "basefontTranslator", or a "blockQuoteTranslator"),
// otherwise use contentTranslator.
//
if (name.equals(AbstractDocument.ContentElementName)) {
AttributeSet a = e.getAttributes();
String tagName = (String)a.getAttribute(Constants.HTMLTagAttribute);
//String tagName = "Tim's Doh Boy";
String styleName = (String)a.getAttribute(AttributeSet.NameAttribute);
String elementName = (String)a.getAttribute(AbstractDocument.ElementNameAttribute);
HTMLDebug.println("writeLeaf(): tagname = " + tagName + " styleName = " + styleName + " elementName " + elementName);
if (tagName != null)
name = tagName;
else if (styleName != null)
name = styleName;
else if (elementName != null && elementName.equals(Constants.PRELINE) && styleName != null)
name = styleName;
else if (elementName == null && styleName != null)
name = styleName;
//
// For some reason, there is a blank content at the end of each doc.
// Need to check for this case.
//
if (tagName != null || styleName != null || elementName != null)
lt = getLeafTranslator(name);
}
//
// Some other leaf, e.g., imgTranslator, hrTranslator,
//
else {
lt = getLeafTranslator(name);
}
//
// HR is a special leaf, so indent like a
// paragraph before writing.
//
if (name.equals(Constants.HR) && indenting == true) {
write(w, indent);
}
// Run it.
if (lt != null)
lt.translate(w, parent, e);
}
/**
* Generate tags to output in upper case.
*/
public void setUpperCase() {
lowercase = false;
}
/**
* Generate tags to output in lower case (default).
*/
public void setLowerCase() {
lowercase = true;
}
/**
* Indent HTML tags.
*/
public void setIndent() {
indenting = true;
}
/**
* No indenting of HTML tags.
*/
public void setNoIndent() {
indenting = false;
}
/**
* Walks the element tree and calls writeBranch() or writeLeaf()
* not assuming any particular element structure.
*/
public void writeBranch(Writer w, String indent, Element e) {
String name;
if (e.isLeaf()) {
AttributeSet a = e.getAttributes();
writeLeaf(w, indent, e.getParentElement(), e);
}
else {
String elementName = e.getName();
if (elementName.equals(AbstractDocument.SectionElementName))
// Force the body translator for a "section" element.
name = Constants.BODY;
// Use "p", "h1", "h2" as name to get translator.
else if (elementName.equals(AbstractDocument.ParagraphElementName)) {
AttributeSet a = e.getAttributes();
AttributeSet style = a.getResolveParent();
name = (String)style.getAttribute(AttributeSet.NameAttribute);
// FXME: This name may be "ul li p" so just use "p" translator.
if (name.endsWith(" p"))
name = "p";
}
// Use "ul", "li" as name to get translator.
else {
name = elementName;
}
// For some reason, there is an element at the top
// called "default".
// Skip it.
if (name.equals("default"))
name = "p";
//
// Get impliedp attribute.
//
AttributeSet attrs = e.getAttributes();
String value = (String)attrs.getAttribute(Constants.IMPLIEDP);
boolean impliedp = false;
if (value != null && value.equals(Constants.IMPLIEDP))
impliedp = true;
//
// If indenting turned on, write out indent for all paragraphs.
// except for PRE or impliedp's.
//
if (indenting == true) {
if (!name.equals(Constants.PRELINE) && !impliedp)
write(w, indent);
}
//
// Don't write out any implied p start tags.
//
if (impliedp == true) {
//System.out.println("name has impliedp: " + name);
}
else {
BranchTranslator bt = getBranchTranslator(name);
//
// If no indenting, add an extra \n for readability
// and if not a PRE.
//
if (indenting == false && !name.equals(Constants.PRELINE))
write(w,"\n");
// Run it.
bt.translate(w, e);
}
//
// Now traverse the children of this branch element
//
int n = e.getElementCount();
for (int i = 0; i < n; i++) {
Element elem = e.getElement(i);
if (indenting == true)
writeBranch(w, indent + " ", elem);
else
writeBranch(w, "", elem);
}
//
// Don't write out any implied p end tags.
//
if (value != null && value.equals(Constants.IMPLIEDP))
write(w, "");
else
writeEndTag(w, name, indent);
}
}
/**
* Write <HEAD> tag.
*/
public void writeHead(Writer w, Element e) {
BranchTranslator bt = getBranchTranslator(Constants.HEAD);
// Run it.
bt.translate(w, e);
}
/**
* Write a start tag <tag> with a \n.
*/
public void writeStartTag(Writer w, String tag) {
if (!lowercase)
tag.toUpperCase();
write(w, "<" + tag + ">\n");
}
/**
* Write an end tag </tag> with a \n.
*/
public void writeEndTag(Writer w, String tag) {
if (!lowercase)
tag.toUpperCase();
write(w, "</" + tag + ">\n");
}
/**
* Write an end tag </tag> with a \n and indenting.
*/
public void writeEndTag(Writer w, String tag, String indent) {
if (!lowercase)
tag.toUpperCase();
//
// No indenting for PRE, P, H end tags.
//
if (tag.equals(Constants.PRE) ||
tag.equals(Constants.P) ||
tag.equals(Constants.H1) ||
tag.equals(Constants.H2) ||
tag.equals(Constants.H3) ||
tag.equals(Constants.H4) ||
tag.equals(Constants.H5) ||
tag.equals(Constants.H6)) {
write(w, "</" + tag + ">\n");
}
//
// Just a CR for DT, DD
//
else if (tag.equals(Constants.DT) ||
tag.equals(Constants.LI) ||
tag.equals(Constants.DD)) {
write(w, CR);
}
/*
//
// CR after MENU, OL, UL
//
else if (tag.equals(MENU) ||
tag.equals(DL) ||
tag.equals(OL) ||
tag.equals(UL) {
if (indenting == true)
write(w, indent + "</" + tag + ">\n");
else
write(w, "</" + tag + ">\n");
}
*/
//
// Check if an end tag is even required.
//
else if (!tag.equals(Constants.LI) &&
!tag.equals(Constants.DD) &&
!tag.equals(Constants.DT) &&
!tag.equals(Constants.HR) &&
!tag.equals(Constants.PRELINE)) {
if (indenting == true)
write(w, indent + "</" + tag + ">\n");
else
write(w, "</" + tag + ">\n");
}
}
/**
* Write a string out
*/
public void write(Writer w, String str) {
HTMLDebug.println("Output=>" + str + "<=");
int len = str.length();
for (int i = 0; i < len; i++) {
try {
w.write(str.charAt(i));
} catch (IOException e) {
System.out.println("HTMLWriter.write: " + str + " " + e);
}
}
}
/**
* Converts value to lower case if lowercase flag it set.
* otherwiser, converts to upper case.
*/
private String convertCase(String val) {
if (lowercase)
return val.toLowerCase();
else
return val.toUpperCase();
}
/**
* Converts an alignment value to string value
**/
private String toAlignString(int align) {
String alignstr = "left";
switch (align) {
case StyleConstants.ALIGN_LEFT:
alignstr = "left";
break;
case StyleConstants.ALIGN_RIGHT:
alignstr = "right";
break;
case StyleConstants.ALIGN_CENTER:
alignstr = "center";
break;
/*
case StyleConstants.ALIGN_JUSTIFIED:
alignstr = "left";
break;
*/
}
return alignstr;
}
/**
* Compares the content's fg color in style with surround
* styles (tagstyles) or the resolve parent to determine
* if the fg color needs to be written.
*/
private boolean writeColor(AttributeSet pstyle, Vector tagstyles,
AttributeSet style) {
Color fg = StyleConstants.getForeground(style);
//
// Check if any tag styles defines this fg color.
// If so, then no need for a color attribute.
// FIX ME to look in correct nested order.
// Inner most attributes take precedence.
//
if (tagstyles != null) {
for (int i = 0; i < tagstyles.size(); i ++) {
Style tagstyle = (Style)tagstyles.elementAt(i);
if (fg == StyleConstants.getForeground(tagstyle))
return false;
}
}
//
// Check if resolve parent defines this fg color
//
if (fg == StyleConstants.getForeground(pstyle))
return false;
return true;
}
/**
* Compares the content's font family in style with surround
* styles (tagstyles) or the resolve parent to determine
* if the fg color needs to be written.
*/
private boolean writeFamily(AttributeSet pstyle, Vector tagstyles, AttributeSet style) {
String family = StyleConstants.getFontFamily(style);
//
// Check if any tag styles define this font family.
// If so, then no need for a font face attribute.
// FIX ME to look in correct nested order.
// Inner most attributes take precedence.
//
if (tagstyles != null) {
for (int i = 0; i < tagstyles.size(); i ++) {
Style tagstyle = (Style)tagstyles.elementAt(i);
if (family == StyleConstants.getFontFamily(tagstyle))
return false;
}
}
//
// Check if resolve parent defines this fg color
//
if (family == StyleConstants.getFontFamily(pstyle))
return false;
return true;
}
/**
* Compares the content's font size in style with surround
* styles (tagstyles) or the resolve parent to determine
* if the fg color needs to be written.
*/
private boolean writeSize(AttributeSet pstyle, Vector tagstyles, AttributeSet style) {
int ptSize = StyleConstants.getFontSize(style);
//
// Check if any tag styles defines this size.
// If so, then no need for a size attribute.
// FIX ME to look in correct nested order.
// Inner most attributes take precedence.
//
if (tagstyles != null) {
for (int i = 0; i < tagstyles.size(); i ++) {
Style tagstyle = (Style)tagstyles.elementAt(i);
if (ptSize == StyleConstants.getFontSize(tagstyle))
return false;
}
}
//
// Check if resolve parent defines this fg color
//
if (ptSize == StyleConstants.getFontSize(pstyle))
return false;
return true;
}
/**
* Determines of the <font> tag needs to be written.
*/
private boolean writeFontTag(AttributeSet pstyle, Vector tagstyles, AttributeSet style) {
if (writeColor(pstyle, tagstyles, style))
return true;
if (writeSize(pstyle, tagstyles, style))
return true;
if (writeFamily(pstyle, tagstyles, style))
return true;
return false;
}
/**
* Determines if the <b> tag needs to be written by
* checking surround tags or resolve parent.
*/
private boolean writeBoldTag(AttributeSet pstyle, Vector tagstyles,
AttributeSet style) {
if (StyleConstants.isBold(style)) {
//
// Check if any of the surround tags define bold.
// If so, then no need to write out a bold tag.
//
if (tagstyles != null) {
for (int i = 0; i < tagstyles.size(); i ++) {
Style tagstyle = (Style)tagstyles.elementAt(i);
if (StyleConstants.isBold(tagstyle))
return false;
}
}
//
// If the resolve parent defines bold then
// no need to write out bold tag.
//
if (StyleConstants.isBold(pstyle))
// parent and tag style is not bold so <b> tag is needed
return false;
return true;
}
else
return false;
}
/**
* Determines if the <i> tag needs to be written by
* checking surround tags or resolve parent.
*/
private boolean writeItalicTag(AttributeSet pstyle, Vector tagstyles,
AttributeSet style) {
if (StyleConstants.isItalic(style)) {
//
// Check if any of the surround tags define bold.
// If so, then no need to write out a bold tag.
//
if (tagstyles != null) {
for (int i = 0; i < tagstyles.size(); i ++) {
Style tagstyle = (Style)tagstyles.elementAt(i);
if (StyleConstants.isItalic(tagstyle))
return false;
}
}
//
// If the resolve parent defines italic then
// no need to write out italic tag.
//
if (StyleConstants.isItalic(pstyle))
// parent and tag style is not italic so <i> tag is needed
return false;
return true;
}
else
return false;
}
/**
* Determines if the <u> tag needs to be written by
* checking surround tags or resolve parent.
*/
private boolean writeUnderlineTag(AttributeSet pstyle, Vector tagstyles,
AttributeSet style) {
if (StyleConstants.isUnderline(style)) {
//
// Check if any of the surround tags define underlining.
// If so, then no need to write out a underline tag.
//
if (tagstyles != null) {
for (int i = 0; i < tagstyles.size(); i ++) {
Style tagstyle = (Style)tagstyles.elementAt(i);
if (StyleConstants.isUnderline(tagstyle))
return false;
}
}
//
// If the resolve parent defines fold then
// no need to write out underlinen tag.
//
if (StyleConstants.isUnderline(pstyle))
// parent and tag style is not underline so <u> tag is needed
return false;
return true;
}
else
return false;
}
/**
* Checks to see if the char attributes are necessary
* before writing. The char attribute may already be
* set in the parent or in the style for the surrounding
* tags (tagstyles).
*/
private void writeContent(Writer w, Vector tagstyles, Element e, Element parent) {
AttributeSet style = e.getAttributes();
AttributeSet pattrs = parent.getAttributes();
AttributeSet pstyle = pattrs.getResolveParent(); // Paragraph
//
// Sanity check.
//
//if (tagstyle == null)
//tagstyle = pstyle;
//
// Write out "<b>", "<i>", or"<u>"
// If parent is bold, then no need to write
// bold for this content. Same for italic, underline.
//
String b = "b";
String i = "i";
String u = "u";
//
// If the parent's style is not bold &&
// the style for this tag is not bold &&
// the style for this content is bold
// then write out a <b>
//
boolean boldtag = writeBoldTag(pstyle, tagstyles, style);
if (boldtag)
write(w, "<" + convertCase(b) + ">");
boolean italictag = writeItalicTag(pstyle, tagstyles, style);
if (italictag)
write(w, "<" + convertCase(i) + ">");
boolean underlinetag = writeUnderlineTag(pstyle, tagstyles, style);
if (underlinetag)
write(w, "<" + convertCase(u) + ">");
// Write "<font"
boolean fonttag = writeFontTag(pstyle, tagstyles, style);
if (fonttag) {
inFont++;
write(w, "<" + convertCase(Constants.FONT));
}
// Write " color=red"
boolean colortag = writeColor(pstyle, tagstyles, style);
if (colortag) {
Color fg = StyleConstants.getForeground(style);
try {
String hexstr = Utilities.colorToHex(fg);
write(w, " " + convertCase(Constants.COLOR) + "=" + convertCase(hexstr));
}
catch (Throwable ex) {
HTMLDebug.println("Unable to convert Color string:" + fg);
}
}
//
// Write " size=+n"
//
boolean sizetag = writeSize(pstyle, tagstyles, style);
if (sizetag) {
StyleSheet ss = StyleReader.getStyleSheet();
int ptSize = StyleConstants.getFontSize(style);
// Convert pt size to a relative value before appending.
int relSize = ss.getRelSize(ptSize);
if (relSize < 0)
write(w, " " + convertCase(Constants.SIZE) + "=" + relSize);
else
write(w, " " + convertCase(Constants.SIZE) + "=+" + relSize);
}
// Write " face=times"
// Fix later, this attribute should go away, not 3.2!
boolean familytag = writeFamily(pstyle, tagstyles, style);
if (familytag) {
String font = StyleConstants.getFontFamily(style);
write(w, " " + convertCase(Constants.FACE) + "=\"" + font + "\"");
}
// Close off <font, if we wrote attributes for this content.
if (fonttag) {
write(w, ">");
}
// Write out the actual content.
String name = (String)style.getAttribute(AttributeSet.NameAttribute);
if (name.equals(Constants.PRE)) {
writePreText(w, e);
}
else
writeText(w, e);
// Close off <FONT>
if (fonttag) {
write(w, "</" + convertCase(Constants.FONT) + ">");
inFont--;
}
// Close off b, i, or u.
if (underlinetag)
write(w, "</" + convertCase(u) + ">");
if (italictag)
write(w, "</" + convertCase(i) + ">");
if (boldtag)
write(w, "</" + convertCase(b) + ">");
}
/**
* Writes out content for this element.
* Strips off the extra \n added by the HTMLDocument reader
* needed for the editing model.
*/
private void writeText(Writer w, Element e) {
try {
StyledDocument doc = (StyledDocument)e.getDocument();
String text = doc.getText(e.getStartOffset(),
e.getEndOffset() - e.getStartOffset());
if (text.endsWith("\n")) {
writeText(w, doc.getText(e.getStartOffset(),
e.getEndOffset() - e.getStartOffset()-1));
}
else
writeText(w, doc.getText(e.getStartOffset(),
e.getEndOffset() - e.getStartOffset()));
} catch (BadLocationException ex) {
HTMLDebug.println("HTMLWriter.writeText:" + e);
}
}
/**
* Writes out content for this element.
* Don't strip off the extra \n added by the HTMLDocument reader
* needed for the editing model.
*/
private void writePreText(Writer w, Element e) {
if (writePre == true && nPrelines >= 0) {
try {
StyledDocument doc = (StyledDocument)e.getDocument();
String text = doc.getText(e.getStartOffset(),
e.getEndOffset() - e.getStartOffset());
//
// If text is empty, then write a \n because
// this was a blank line.
//
if (e.getStartOffset() == e.getEndOffset() && nPrelines > 0) {
writeChar(w, '\n');
writePre = false;
}
else if (nPrelines == 0 && e.getEndOffset() - 1 > e.getStartOffset() &&
doc.getText(e.getStartOffset(), e.getEndOffset() - e.getStartOffset()).endsWith("\n")) {
writeText(w, doc.getText(e.getStartOffset(),
e.getEndOffset() - e.getStartOffset() - 1));
writePre = true;
}
else {
writeText(w, doc.getText(e.getStartOffset(),
e.getEndOffset() - e.getStartOffset()));
writePre = true;
}
} catch (BadLocationException ex) {
HTMLDebug.println("HTMLWriter.writeText:" + e);
}
}
//writePre = false;
}
/**
* Write a char out
*/
public void writeChar(Writer w, char c) {
HTMLDebug.println("Output=>" + c + "<=");
try {
switch (c) {
case '<': w.write("<"); break;
case '>': w.write(">"); break;
case '&': w.write("&"); break;
case '"': w.write("""); break;
default:
if ((c == '\n') || (c == '\t') || (c == '\r'))
w.write(c);
else if ((c < ' ') || (c > 127)) {
w.write("");
w.write(String.valueOf((int)c));
w.write(";");
} else {
w.write(c);
}
}
}
catch (IOException e) {
System.out.println("HTMLWriter.write: " + c + " " + e);
}
}
private void writeText(Writer w, String data) {
int len = data.length();
for (int i = 0; i < len; i++) {
writeChar(w, data.charAt(i));
}
}
}